package magent

import (
	"fmt"
	"time"

	"github.com/shirou/gopsutil/cpu"
	"github.com/shirou/gopsutil/disk"
	"github.com/shirou/gopsutil/mem"
	"github.com/shirou/gopsutil/net"
)

type name struct {
}

// RealInfo stand for system info of cpu, memory, network io and disk io.
type RealInfo struct {
	CPUIdle        float64 `json:"idle_cpu_percent"`
	MemTotal       uint64  `json:"total_memory"`
	MemAvailable   uint64  `json:"available_memory"`
	MemUsedPercent float64 `json:"used_memory_percent"`
	NetSent        uint64  `json:"network_bytes_sent"`
	NetRecv        uint64  `json:"network_bytes_recv"`
	DiskRead       uint64  `json:"disk_read_bytes"`
	DiskWrite      uint64  `json:"disk_write_bytes"`
	Time           string  `json:"generate_time"`
}

func realInfo() (*RealInfo, error) {
	var ri RealInfo

	// Get CPU Idle.
	ci, err := cpu.Percent(time.Second, false)
	if err != nil {
		return nil, fmt.Errorf("Cannot get cpu idle, %v.", err)
	}
	ri.CPUIdle = ci[0]

	// Get Memory info.
	vm, err := mem.VirtualMemory()
	if err != nil {
		return nil, fmt.Errorf("Cannot get memory info, %v.", err)
	}
	ri.MemTotal = uint64(vm.Total / 1024.0 / 1024.0)
	ri.MemAvailable = uint64(vm.Available / 1024.0 / 1024.0)
	ri.MemUsedPercent = vm.UsedPercent

	// Get Network io.
	ni, err := net.IOCounters(false)
	if err != nil {
		return nil, fmt.Errorf("Cannot get network io, %v", err)
	}
	ri.NetSent = ni[0].BytesSent
	ri.NetRecv = ni[0].BytesRecv

	// Get disk io.
	var diTotal disk.IOCountersStat
	dis, err := disk.IOCounters()
	for _, di := range dis {
		diTotal.ReadBytes += di.ReadBytes
		diTotal.WriteBytes += di.WriteBytes
		diTotal.ReadTime += di.ReadTime
		diTotal.WriteTime += di.WriteTime
	}
	if diTotal.ReadTime == 0 {
		ri.DiskRead = 0
	} else {
		ri.DiskRead = uint64(1.0 * diTotal.ReadBytes / diTotal.ReadTime * 1000)
	}

	if diTotal.WriteTime == 0 {
		ri.DiskWrite = 0
	} else {
		ri.DiskWrite = uint64(1.0 * diTotal.WriteBytes / diTotal.WriteTime * 1000)
	}

	// Get time.
	ri.Time = time.Now().Format("2006-01-02 15:04")

	return &ri, nil
}
